package com.hunantv.mglive.utils;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.hunantv.mglive.R;
import com.hunantv.mglive.ui.discovery.publisher.pic.LocalPhotoInfo;
import com.hunantv.mglive.ui.discovery.publisher.pic.QQAlbumInfo;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Thumbnails;
import android.text.TextUtils;
import android.util.Pair;


public class AlbumUtil {
	private static final String TAG = AlbumUtil.class.getSimpleName();

	private final static String IMAGE_ORDER_BY = Images.ImageColumns._ID + " DESC";

	public static final String[] PROJECTION_THUMB = new String[] { Thumbnails.DATA };

	private static final String[] PROJECTION_BUCKET = { Images.ImageColumns.BUCKET_ID,
			Images.ImageColumns.BUCKET_DISPLAY_NAME,
			"MAX(" + Images.ImageColumns._ID + ") as " + Images.ImageColumns._ID, Images.ImageColumns.DATE_MODIFIED,
			Images.ImageColumns.DATA, Images.ImageColumns._ID, Images.ImageColumns.ORIENTATION };

	private static final String BUCKET_SELECTION = Images.ImageColumns.SIZE + ">0" + ") GROUP BY (1";
	private static final String BUCKET_ORDER_BY = "" + Images.ImageColumns._ID + " DESC";

	private static final String[] PROJECTION_BUCKET_COUNT = { "count( " + Images.ImageColumns.DATA + ") as count" };
	private static final String BUCKET_COUNT_WHERE = Images.ImageColumns.SIZE + ">0";

	public static SimpleDateFormat dateFormatter = new SimpleDateFormat();

	public static final int PHOTO_WIDTH = 170;

	public static final int PHOTO_HEIGHT = 170;

	public static int albumListFirstVisiblePos = 0;

	private static Map<String, Integer> pathWHMap = new HashMap<String, Integer>();

	private static final int MAX_PHOTO_WIDTH_OF_CACHE = 65535;

	private static final int MAX_PHOTO_HEIGHT_OF_CACHE = 65535;

	// 最大可选择的图片个数
	public static final int PHOTO_SELECT_ITEM_MAX = 20;

	/**
	 * 记录发送图片后的位置状态。两次操作间隔超过有效时间，状态便无效
	 */
	public static final long PHOTO_SLOT_TIME = 5 * 60 * 1000; // 5分钟有效时间
	
	/// 发送照片时的相册
	public static String sLastAlbumPath = "";
	
	/// <AlbumId, PhotoCounts>
	public static HashMap<String, Integer> sLastAlbumPhotoCountMap = new HashMap<String, Integer>();
	public static long sLastAlbumRecordTime = 0;
	
	/// 直接打开上次发送时的照片列表
	public static String sLastAlbumId;
	public static String sLastAlbumName;
	
	// 发送照片后记录的信息
	public static final String ALBUM_FILE_NAME = "album_file";
	public static final String ALBUM_KEY_ID = "album_key_id";
	public static final String ALBUM_KEY_NAME = "album_key_name";

	/**
	 * 当前相册最后一次选择item时的位置。 用于从相册列表进图片列表时，定位到最后一次选择的item位置。退出相册列表后即清除
	 */
	/// <AlbumId, <Path, Position>>
	public static HashMap<String, LinkedHashMap<String, Integer>> sSelectItemPosMap = new HashMap<String, LinkedHashMap<String, Integer>>();
	
	/// <PathString, Pair<AlbumId, AlbumName>>
	public static HashMap<String, Pair<String, String>> sSelectItemAlbum = new HashMap<String, Pair<String, String>>();

	static {
		dateFormatter.applyPattern("yyyy-MM-dd:HH:mm:ss:SSS");
	}

	public static List<LocalPhotoInfo> queryImages(Context ctx, String selector, int limit, boolean isContainGif) {

		Cursor imageCursor = null;
		List<LocalPhotoInfo> imageList = new ArrayList<LocalPhotoInfo>();
		try {
			imageCursor = AlbumUtil.queryImages(ctx, selector, null, limit);
			boolean isHighVer = Build.VERSION.SDK_INT >= 16;
			getImageList(imageCursor, imageList, -1, isContainGif, limit, isHighVer);
		} catch (Exception e) {
			
		} finally {
			if (imageCursor != null) {
				imageCursor.close();
			}
		}

		return imageList;
	}

	private static void getImageList(Cursor imageCursor, List<LocalPhotoInfo> imageList, int limitWidth,
			boolean isContainGif, int maxCount, boolean isHighVersion) {
		int count = imageCursor.getCount();
		if (count > 0) {
			int columnData = imageCursor.getColumnIndexOrThrow(Images.Media.DATA);
			int orientationColumnId = imageCursor.getColumnIndexOrThrow(Images.ImageColumns.ORIENTATION);
			int modifiedColumnId = imageCursor.getColumnIndexOrThrow(Images.ImageColumns.DATE_MODIFIED);
			int widthId = 0;
			if (isHighVersion)
				widthId = imageCursor.getColumnIndexOrThrow(Images.ImageColumns.WIDTH);
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;
			int[] whArray = new int[2];
			int tempCount = 0;
			boolean isWidthNull = false;
			while (imageCursor.moveToNext()) {
				String imagePath = imageCursor.getString(columnData);
				long modifiedTime = imageCursor.getLong(modifiedColumnId);
				if (lastModify < modifiedTime)
					lastModify = modifiedTime;
				if (isHighVersion) {
					int width = imageCursor.getInt(widthId);
					if (width == 0)
						isWidthNull = true;
				}
				if (maxCount > 0 && tempCount >= maxCount)
					break;
				if (imagePath != null) {
					File f = new File(imagePath);
					if (!f.exists())
						continue;
					if (limitWidth > 0 && (!isHighVersion || isWidthNull)) {
						getWHByPath(imagePath, options, whArray);
						if (whArray[0] >= limitWidth || whArray[1] >= limitWidth) {
							LocalPhotoInfo photoInfo = new LocalPhotoInfo();
							photoInfo.path = imagePath;
							photoInfo.modifiedDate = modifiedTime;
							photoInfo.orientation = imageCursor.getInt(orientationColumnId);
							imageList.add(photoInfo);
							tempCount++;
						}
					} else {
						LocalPhotoInfo photoInfo = new LocalPhotoInfo();
						photoInfo.path = imagePath;
						photoInfo.modifiedDate = imageCursor.getLong(modifiedColumnId);
						photoInfo.orientation = imageCursor.getInt(orientationColumnId);
						imageList.add(photoInfo);
						tempCount++;
					}
				}
				isWidthNull = false;
			}
		}
	}

	static String[] columns;
	static {
		if (Build.VERSION.SDK_INT >= 16) {
			columns = new String[] { Images.ImageColumns._ID, Images.Media.DATA,
					Images.ImageColumns.DATE_MODIFIED, Images.ImageColumns.ORIENTATION,
					Images.ImageColumns.SIZE, Images.ImageColumns.WIDTH };
		} else {
			columns = new String[] { Images.ImageColumns._ID, Images.Media.DATA,
					Images.ImageColumns.DATE_MODIFIED, Images.ImageColumns.ORIENTATION,
					Images.ImageColumns.SIZE };
		}
	}

	private static Cursor queryImages(Context context, String selection, String[] selectionArgs, int limit) {
		Uri uri = null;
		if (limit > 0) {
			Uri.Builder builder = Images.Media.EXTERNAL_CONTENT_URI.buildUpon();
			builder.appendQueryParameter("limit", String.valueOf(limit));
			uri = builder.build();
		} else {
			uri = Images.Media.EXTERNAL_CONTENT_URI;
		}
		return context.getContentResolver().query(uri, columns, selection, selectionArgs, IMAGE_ORDER_BY);

	}

	static List<LocalPhotoInfo> cacheRecentImages;

	public static List<LocalPhotoInfo> queryRecentImages(Context ctx, int limitWidth, int limit, boolean isContainGif) {
		Cursor imageCursor = null;
		String selector = null;
		if (limit <= 0) {
			throw new IllegalArgumentException("limit must be great than 0");
		}
		List<LocalPhotoInfo> imageList = new ArrayList<LocalPhotoInfo>();
		boolean isHighVer = false;
		if (Build.VERSION.SDK_INT >= 16)
			isHighVer = true;
		try {
			if (isHighVer) {
				selector = Images.ImageColumns.SIZE + ">? and (" + Images.ImageColumns.WIDTH + ">=? or "
						+ Images.ImageColumns.WIDTH + " IS NULL or " + Images.ImageColumns.HEIGHT + ">=? or "
						+ Images.ImageColumns.HEIGHT + " IS NULL " + ")) GROUP BY (" + Images.Media.DATA;
				imageCursor = AlbumUtil.queryImages(ctx, selector,
						new String[] { String.valueOf(0), String.valueOf(limitWidth), String.valueOf(limitWidth) },
						limit);
				getImageList(imageCursor, imageList, limitWidth, isContainGif, limit, isHighVer);
			} else {
				selector = Images.ImageColumns.SIZE + ">10000 " + ") GROUP BY (" + Images.Media.DATA;
				int realLimit = limit * 6;
				Uri uri = null;
				Uri.Builder builder = Images.Media.EXTERNAL_CONTENT_URI.buildUpon();
				builder.appendQueryParameter("limit", String.valueOf(realLimit));
				uri = builder.build();
				imageCursor = ctx.getContentResolver().query(uri, columns, selector, null, IMAGE_ORDER_BY);
				getImageList(imageCursor, imageList, limitWidth, isContainGif, limit, isHighVer);
			}

			cacheRecentImages = imageList;
		} catch (Exception e) {
		} finally {
			if (imageCursor != null) {
				imageCursor.close();
			}
		}

		return imageList;
	}

	private static void getWHByPath(String imagePath, BitmapFactory.Options options, int[] whArray) {
		Integer whObj = pathWHMap.get(imagePath);
		int w = 0;
		int h = 0;
		if (whObj == null) {
			BitmapFactory.decodeFile(imagePath, options);
			w = options.outWidth;
			h = options.outHeight;
			if (options.outWidth > MAX_PHOTO_WIDTH_OF_CACHE || options.outHeight > MAX_PHOTO_HEIGHT_OF_CACHE) {

			} else {
				int wh = (options.outWidth << 16 & 0xffff0000) | (options.outHeight & 0x0000ffff);
				whObj = Integer.valueOf(wh);
				pathWHMap.put(imagePath, whObj);
			}
		} else {
			w = (whObj.intValue() >> 16) & 0x0000ffff;
			h = (whObj.intValue() & 0x0000ffff);
		}
		whArray[0] = w;
		whArray[1] = h;
	}

	private static List<QQAlbumInfo> albumCache;

	private static long lastModify;
	
	public static List<QQAlbumInfo> getCacheBuckets() {
		return albumCache;
	}

	public static long getCacheLastModify() {
		return lastModify;
	}

	public static List<QQAlbumInfo> queryBuckets(Context context, int type, boolean isContainGif) {
		ArrayList<QQAlbumInfo> bucketList = new ArrayList<QQAlbumInfo>();
		Cursor cursor = null;
		try {
			cursor = context.getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI, PROJECTION_BUCKET,
					BUCKET_SELECTION, null, BUCKET_ORDER_BY);
			if (cursor != null) {
				while (cursor.moveToNext()) {
					String bucketId = cursor.getString(cursor.getColumnIndex(Images.Media.BUCKET_ID));
					String name = cursor.getString(cursor.getColumnIndex(Images.Media.BUCKET_DISPLAY_NAME));
					if (TextUtils.isEmpty(bucketId) || TextUtils.isEmpty(name)) {
						continue;
					}

					QQAlbumInfo bucketInfo = new QQAlbumInfo();
					bucketInfo.name = name;
					bucketInfo._id = bucketId;
					if (!bucketList.contains(bucketInfo)) {
						String imagePath = cursor.getString(cursor.getColumnIndex(Images.ImageColumns.DATA));
						long imageDate = cursor.getLong(cursor.getColumnIndex(Images.ImageColumns.DATE_MODIFIED));
						long coverId = cursor.getLong(cursor.getColumnIndex(Images.ImageColumns._ID));
						bucketInfo.cover = new LocalPhotoInfo();
						bucketInfo.coverDate = imageDate;
						bucketInfo.cover.path = imagePath;
						bucketInfo.cover._id = coverId;
						bucketInfo.cover.modifiedDate = imageDate;
						if (lastModify < imageDate)
							lastModify = imageDate;
						bucketInfo.cover.orientation = cursor.getInt(cursor
								.getColumnIndex(Images.ImageColumns.ORIENTATION));
						bucketList.add(bucketInfo);
					}
				}
				albumCache = bucketList;
				for (QQAlbumInfo bucketInfo : bucketList) {
					String selection = Images.ImageColumns.BUCKET_ID + "='" + bucketInfo._id + "'" + " and "
							+ BUCKET_COUNT_WHERE;
					int bucketCount = queryNumEntries(context, Images.Media.EXTERNAL_CONTENT_URI,
							PROJECTION_BUCKET_COUNT, selection);
					bucketInfo.imageCount = bucketCount;
				}
			}
		} catch (Exception e) {
			
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return bucketList;
	}

	private static LocalPhotoInfo getFirstPhotoInfo(Cursor imageCursor, int limitSize) {
		LocalPhotoInfo cover = new LocalPhotoInfo();
		int columnData = imageCursor.getColumnIndexOrThrow(Images.Media.DATA);
		int columnId = imageCursor.getColumnIndexOrThrow(Images.Media._ID);
		int modifiedColumnId = imageCursor.getColumnIndexOrThrow(Images.ImageColumns.DATE_MODIFIED);
		BitmapFactory.Options options = new BitmapFactory.Options();
		int[] whArray = new int[2];
		while (imageCursor.moveToNext()) {
			String imagePath = imageCursor.getString(columnData);
			long id = imageCursor.getLong(columnId);
			if (imagePath != null && imagePath.length() > 0) {
				File file = new File(imagePath);
				if (file.exists() && file.isFile()) {
					if (limitSize > 0) {
						getWHByPath(imagePath, options, whArray);
						if (whArray[0] >= limitSize || whArray[1] >= limitSize) {
							cover._id = id;
							cover.path = imagePath;
							cover.modifiedDate = imageCursor.getLong(modifiedColumnId);
						}
					} else {
						cover._id = id;
						cover.path = imagePath;
						cover.modifiedDate = imageCursor.getLong(modifiedColumnId);
					}
					break;
				} else {
					
				}
			}
		}
		return cover;
	}

	public static QQAlbumInfo getCacheRecentBucket() {
		if (cacheRecentImages != null && cacheRecentImages.size() > 0) {
			QQAlbumInfo albumInfo = new QQAlbumInfo();
			albumInfo._id = AlbumConstants.RECENT_ALBUM_ID;
			albumInfo.name = AlbumConstants.RECENT_ALBUM_NAME;
			albumInfo.cover = cacheRecentImages.get(0);
			albumInfo.imageCount = cacheRecentImages.size();
			return albumInfo;
		}
		return null;
	}

	public static QQAlbumInfo queryRecentBucket(Context ctx, int limitSize, int limit, boolean isContainGif) {
		Cursor imageCursor = null;
		String selector = null;
		if (limit <= 0) {
			throw new IllegalArgumentException("limit must be great than 0");
		}
		QQAlbumInfo albumInfo = new QQAlbumInfo();
		albumInfo._id = AlbumConstants.RECENT_ALBUM_ID;
		albumInfo.name = AlbumConstants.RECENT_ALBUM_NAME;
		albumInfo.cover = new LocalPhotoInfo();
		boolean isHighVer = false;
		if (Build.VERSION.SDK_INT >= 16)
			isHighVer = true;
		if (isHighVer) {
			selector = Images.ImageColumns.SIZE + ">? and (" + Images.ImageColumns.WIDTH + ">=? or "
					+ Images.ImageColumns.HEIGHT + ">=? " + ")) GROUP BY (" + Images.Media.DATA;
			try {
				imageCursor = queryImages(ctx, selector, new String[] { String.valueOf(0), String.valueOf(limitSize),
						String.valueOf(limitSize) }, limit);
				int count = imageCursor.getCount();
				List<LocalPhotoInfo> imageList = new ArrayList<LocalPhotoInfo>();
				if (!isContainGif) {
					getImageList(imageCursor, imageList, limitSize, isContainGif, limit, isHighVer);
					count = imageList.size();
				}
				albumInfo.imageCount = count;
				if (count > 0) {
					if (!isContainGif) {
						albumInfo.cover = imageList.get(0);
					} else
						albumInfo.cover = getFirstPhotoInfo(imageCursor, -1);
				}
				albumInfo.imageCount = count;
			} catch (Exception e) {
				
			} finally {
				if (imageCursor != null) {
					imageCursor.close();
				}
			}
		} else {
			selector = Images.ImageColumns.SIZE + ">0" + ") GROUP BY (" + Images.Media.DATA;
			int realLimit = limit * 6;

			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;
			List<LocalPhotoInfo> imageList = new ArrayList<LocalPhotoInfo>();
			try {
				Uri uri = null;
				Uri.Builder builder = Images.Media.EXTERNAL_CONTENT_URI.buildUpon();
				builder.appendQueryParameter("limit", String.valueOf(realLimit));
				uri = builder.build();
				imageCursor = ctx.getContentResolver().query(uri, columns, selector, null, IMAGE_ORDER_BY);
				getImageList(imageCursor, imageList, limitSize, isContainGif, limit, isHighVer);
				albumInfo.imageCount = imageList.size();
				if (imageList.size() > 0) {
					LocalPhotoInfo info = imageList.get(0);
					albumInfo.cover = info;
					albumInfo.coverDate = info.modifiedDate;
				}
			} catch (Exception e) {
			} finally {
				if (imageCursor != null) {
					imageCursor.close();
				}
			}
		}

		return albumInfo;
	}

	public static int queryNumEntries(Context context, Uri uri, String[] projection, String selection) {
		return queryNumEntries(context, uri, projection, selection, null);
	}

	public static int queryNumEntries(Context context, Uri uri, String[] projection, String selection,
			String[] selectionArgs) {
		Cursor cursor = null;
		try {
			cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
			if (cursor.moveToFirst()) {
				return cursor.getInt(0);
			}
		} catch (Throwable e) {
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return 0;
	}

	/**
	 * @param XOrY
	 *            true：X方向动画，false：Y方向动画
	 * @param InOrOut
	 *            true：进入动画，false：退出动画
	 */
	public static void anim(Activity a, boolean XOrY, boolean InOrOut) {
		if (XOrY) {
			if (InOrOut) {
				XInAnim(a);
			} else {
				XOutAnim(a);
			}
		} else {
			if (InOrOut) {
				YInAnim(a);
			} else {
				YOutAnim(a);
			}
		}
	}

	/**
	 * X方向（右->左），进入动画
	 */
	private static void XInAnim(Activity a) {
		a.overridePendingTransition(R.anim.activity_new, R.anim.activity_out);
	}

	/**
	 * X方向（左->右），退出动画
	 */
	private static void XOutAnim(Activity a) {
		a.overridePendingTransition(R.anim.activity_back, R.anim.activity_finish);
	}

	/**
	 * Y方向（下->上），进入动画，
	 */
	private static void YInAnim(Activity a) {
		a.overridePendingTransition(R.anim.activity_2_enter_in, R.anim.activity_2_enter_out);
	}

	/**
	 * Y方向（上->下），退出动画
	 */
	private static void YOutAnim(Activity a) {
		a.overridePendingTransition(R.anim.activity_2_back_in, R.anim.activity_2_back_out);
	}

	public static URL getFileURL(String path) {
		URL url = null;
		File file = new File(path);
		try {
			url = file.toURL();
			String urlStr = url.toString();
			urlStr = urlStr + "?thumb=true";
			url = new URL(urlStr);
		} catch (MalformedURLException e) {
		}
		return url;

	}

	public static void returnToInitActivity(Activity a, Class<?> clazz, Intent intent) {
		intent.setClass(a, clazz);
		intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
		a.startActivity(intent);
		anim(a, true, false);
	}

	public static int getAlbumListFirstVisiblePos() {
		return albumListFirstVisiblePos;
	}

	public static URL generateAlbumThumbURL(LocalPhotoInfo photoInfo, int gridWidth) {
		String protocol = "albumthumb";
		URL url = null;
		photoInfo.thumbWidth = gridWidth;
		photoInfo.thumbHeight = gridWidth;
		String urlPath = LocalPhotoInfo.getUrl(photoInfo);
		try {
			url = new URL(protocol, "", urlPath);
		} catch (MalformedURLException e) {
		}
		return url;
	}

	public static void clearCache() {
		albumCache = null;
	}

	/**
	 * 在退出登录、切换账号后，需要清除当前记录的相册定位信息
	 */
	public static void clearLastAlbumInfo() {
		sLastAlbumPhotoCountMap.clear();
		sLastAlbumPath = null;
		sLastAlbumRecordTime = 0;
		sLastAlbumId = null;
		sLastAlbumName = null;
	}

	public static void clearSelectItemInfo() {
		sSelectItemAlbum.clear();
		sSelectItemPosMap.clear();
	}

    public static final String IS_RECODE_LAST_ALBUMPATH =  "PhotoConst." + "IS_RECODE_LAST_ALBUMPATH";
    public static final String LAST_ALBUMPATH =  "PhotoConst." + "LAST_ALBUMPATH";
    public static final String ALBUM_ID = "ALBUM_ID";
    
	public static void putRecordLastPosData(Intent intent, String albumId, String path, boolean isRecord) {
		if (isRecord) {
			intent.putExtra(IS_RECODE_LAST_ALBUMPATH, isRecord);
			intent.putExtra(ALBUM_ID, albumId);
			intent.putExtra(LAST_ALBUMPATH, path);
		}
	}

	public static void RecordLastPosByIntent(Intent intent) {
		boolean isRecordLastPos = intent.getBooleanExtra(IS_RECODE_LAST_ALBUMPATH, false);
		if (isRecordLastPos) {
			String lastAlbumId = intent.getStringExtra(ALBUM_ID);
			String lastPathString = intent.getStringExtra(LAST_ALBUMPATH);

			if (lastPathString != null && lastAlbumId != null) {
				AlbumUtil.sLastAlbumPath = lastPathString;
				AlbumUtil.sLastAlbumRecordTime = System.currentTimeMillis();
			}
		}
	}
	
	public static void putLastAlbumInfo(Context context, String id, String name) {
		SharedPreferences sp = context.getSharedPreferences(ALBUM_FILE_NAME, Context.MODE_PRIVATE);
		Editor editor = sp.edit();
		editor.putString(ALBUM_KEY_ID, sLastAlbumId);
		editor.putString(ALBUM_KEY_NAME, sLastAlbumName);
		editor.commit();
	}
	
	public static String getLastAlbumId(Context context) {
		SharedPreferences sp = context.getSharedPreferences(ALBUM_FILE_NAME, Context.MODE_PRIVATE);
		return sp.getString(ALBUM_KEY_ID, null);
	}
	
	public static String getLastAlbumName(Context context) {
		SharedPreferences sp = context.getSharedPreferences(ALBUM_FILE_NAME, Context.MODE_PRIVATE);
		return sp.getString(ALBUM_KEY_NAME, null);
	}
}
